#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "sym_table.h"
#include "parser.h"
#include "symbol.h"
#include "error.h"
#include "semantic.h"
#include "gp_list.h"
#include "inter_code.h"
#include "genir.h"

void __print_type(symbol_e type);
bool array_is_initialized(var_t *arr);
void print_array_init_val(var_t *arr);

void show_fun(fun_t *fun);
void print_literal(var_t *var);
void sym_table_scope_destroy(void);
void decl_var(var_t *var);
void def_var(var_t *var);
sym_table_t sym_tab_g;

void create_special_vars(void)
{
	// 函数返回值为空或者表达式为空
	sym_tab_g.void_var = new_void_var();
	int tmp = 0;
	sym_tab_g.zero = new_literal(&tmp, NUM, 0);
	tmp = 1;
	sym_tab_g.one = new_literal(&tmp, NUM, 0);
	tmp = 4;
	sym_tab_g.four = new_literal(&tmp, NUM, 0);
}

void destroy_special_vars(void)
{
	free(sym_tab_g.void_var->note);
	free(sym_tab_g.zero->note);
	free(sym_tab_g.one->note);
	free(sym_tab_g.four->note);

	free(sym_tab_g.void_var);
	free(sym_tab_g.zero);
	free(sym_tab_g.one);
	free(sym_tab_g.four);
	
}
int sym_table_init(void)
{
	memset(&sym_tab_g, 0, sizeof(sym_table_t));
	INIT_LIST_HEAD(&sym_tab_g.var_tab_head);
	INIT_LIST_HEAD(&sym_tab_g.scope.head);

	// 创建特殊变量
	create_special_vars();
	scope_enter(); // 进入全局作用域
	return 0;	
}


void sym_table_destroy(void)
{
	fun_tab_destroy(); // 顺序很重要，fun_tab 要用到 var_tab
    str_tab_destroy();
	var_tab_destroy();

	gp_list_free(&sym_tab_g.var_tab_head);
	sym_table_scope_destroy();
	destroy_special_vars();
}

void print_sym_table_scope(void)
{
	scope_node_t *node;
	list_for_each_entry(node, &sym_tab_g.scope.head, entry) {
		printf("%d/",node->id);
	}
	printf("\n");

}
void scope_enter(void)
{
	scope_node_t *node = malloc(sizeof(scope_node_t));
	if(!node) {
		SYSTEM_FATAL_ERR(MEM_ALLOC_FAILED);
		return;
	}

	node->id = sym_tab_g.scope.scope_id++;
	list_add_tail(&node->entry, &sym_tab_g.scope.head);
	++sym_tab_g.scope.list_len;

	// print_sym_table_scope();
	// if(symb_tab.cur_fun){
	// 	//printf("cur_fun = %p\n", symb_tab.cur_fun);
	// 	fun_scope_enter(symb_tab.cur_fun);
	// }
}


void scope_leave(void)
{
	if(list_empty(&sym_tab_g.scope.head))
		return;
	
	scope_node_t *last_node = container_of(sym_tab_g.scope.head.prev, scope_node_t, entry);
	list_del_init(&last_node->entry);
	free(last_node);
	--sym_tab_g.scope.list_len;
	
	// if(symb_tab.cur_fun){
	// 	fun_scope_leave(symb_tab.cur_fun);
	// }

}


// 变量或者函数声明或者定义的作用域
void get_cur_scope(scope_path_t *scope_path, int symbol_type)
{
	assert(scope_path);
	assert(symbol_type == SYMBOL_TYPE_VAR || symbol_type == SYMBOL_TYPE_FUN);

	int path_len;
	if(symbol_type == SYMBOL_TYPE_VAR) {
		path_len = sym_tab_g.scope.list_len;
	} else {
		// 函数声明或者定义的作用域要去掉最后一个数字
		// 因为不去掉的话表示的是函数参数的作用域
		path_len = sym_tab_g.scope.list_len - 1; 
	}
	assert(path_len > 0);

	int *path = malloc(sizeof(int) * path_len); 
	if(!path){
		SYSTEM_FATAL_ERR(MEM_ALLOC_FAILED);
		return;
	}

	scope_node_t *pos;
	int i = 0;
	list_for_each_entry(pos, &sym_tab_g.scope.head, entry){		
		path[i++] = pos->id;
		if(i == path_len)
			break;
	}
	scope_path->path = path;
	scope_path->path_len = path_len;
}



void var_tab_destroy(void)
{
    var_t *pos;
    struct hlist_node *next;
    unsigned int bkt;
    hash_for_each_safe(sym_tab_g.var_tab, bkt, next, pos, hnode) {
        hlist_del(&pos->hnode);
        var_destroy(pos);
    }
}


// todo 可以改成宏，供其他函数调用
void sym_table_scope_destroy(void)
{
	scope_node_t *cur, *next;
	list_for_each_entry_safe(cur, next, &sym_tab_g.scope.head, entry) {
		list_del(&cur->entry);
		free(cur);
	}
}

void str_tab_destroy(void)
{
    var_t *pos;
    struct hlist_node *next;
    unsigned int bkt;
    hash_for_each_safe(sym_tab_g.str_tab, bkt, next, pos, hnode) {
        hlist_del(&pos->hnode);
        var_destroy(pos);
    }
}

void fun_tab_destroy(void)
{
    fun_t *pos;
    struct hlist_node *next;
    unsigned int bkt;
    hash_for_each_safe(sym_tab_g.fun_tab, bkt, next, pos, hnode) {
        hlist_del(&pos->hnode);
        fun_destroy(pos);
    }
}


int in_same_scope(scope_path_t *p1, scope_path_t *p2)
{
	assert(p1 && p2 && p1->path && p2->path);
	int i = p1->path_len;
	int j = p2->path_len;
	return ((i == j) && (p1->path[i-1] == p2->path[j-1]));
}

// 把常量(字符串除外)加入变量表
void add_literal(var_t *literal)
{
	if(!literal)
		return;

	unsigned int key = my_hash(literal->name);
	hash_add(sym_tab_g.var_tab, &literal->hnode, key);	
	gp_node_add_tail(literal, &sym_tab_g.var_tab_head);
	sym_tab_g.literal_num++;		
}

void add_var(var_t *var)
{
	if(!var)
        return; // 因为语义分析，可能报错，返回的是 NULL

	if(var->is_ext)
		decl_var(var);
	else
		def_var(var);
}


// 仅考虑 var 是 extern
void decl_var(var_t *var)
{
	// 查询函数表
	unsigned int key = my_hash(var->name);
	fun_t *fun;
	int fun_conflict = 0;
	hash_for_each_possible(sym_tab_g.fun_tab, fun, hnode, key) {
		// 跳过错误的符号
   		if (!fun->err_flag && 0 == strcmp(fun->name, var->name)) {  
			if(in_same_scope(&fun->scope_path, &var->scope_path)) {
				fun_conflict = 1;
				break;
			}
        }
    }
	if(fun_conflict) {
		sem_err(REDECLARED_AS_DIFFERENT_KIND_SYMBOL, ERROR, var->name, &fun->line_num);
		var_destroy(var);
		return;
	}
	// 不同作用域的 extern xxx, 类型要一致
	// 如果有全局的 xxx 变量定义，extern xxx 要和它类型一致 

	int same_scope = 0;
	var_t *cur;   
	var_t *decl_var = NULL; 
	var_t *same_scp_var = NULL;

	// 查询变量表
	hash_for_each_possible(sym_tab_g.var_tab, cur, hnode, key) {
		// 跳过错误的符号
   		if (!var->err_flag && 0 == strcmp(cur->name, var->name)) {  
			//如果是声明或者是全局的定义
			if(cur->is_ext || IS_GLOBAL(cur)) 
				decl_var = cur;
			if(in_same_scope(&cur->scope_path, &var->scope_path)) {
				same_scp_var = cur;	
				break;
			}
        }
    }

	if(same_scp_var){	
		// 遇到了局部变量定义
		if(!same_scp_var->is_ext && IS_LOCAL(same_scp_var)) { 
			// error: extern declaration of ‘xxxx’ follows declaration with no linkage
			sem_err(EXTERN_DECLARATION_AND_NO_LINKAGE_DECLARATION_CONFLICTING, 
							ERROR, var->name,  &same_scp_var->line_num);
		} else { // 全局定义，全局声明，局部声明
			if(!var_type_exact_match(var, same_scp_var)) {
				sem_err(CONFLICTING_TYPES, ERROR, var->name, &same_scp_var->line_num);				
			}		
		}
		var_destroy(var);
		return;
	}

	if(decl_var) {
		if(!var_type_exact_match(var, decl_var)) {
			sem_err(CONFLICTING_TYPES, ERROR, var->name, &decl_var->line_num);
			var_destroy(var);
			return;
		}
	}

	hash_add(sym_tab_g.var_tab, &var->hnode, key);	
	gp_node_add_tail(var, &sym_tab_g.var_tab_head);
	sym_tab_g.var_num++;
}



// 仅考虑 var 是定义
// 同一个作用域，发现定义就报错（强弱符号比较复杂，这里简化处理）
void def_var(var_t *var)
{
	// 查询函数表
	unsigned int key = my_hash(var->name);
	fun_t *fun;
	int fun_conflict = 0;
	hash_for_each_possible(sym_tab_g.fun_tab, fun, hnode, key) {
		// 跳过错误的符号
   		if (!fun->err_flag && 0 == strcmp(fun->name, var->name)) {  
			if(in_same_scope(&fun->scope_path, &var->scope_path)) {
				fun_conflict = 1;
				break;
			}
        }
    }
	if(fun_conflict) {
		sem_err(REDECLARED_AS_DIFFERENT_KIND_SYMBOL, ERROR, var->name, &fun->line_num);
		var_destroy(var);
		return;
	}
	// 不同作用域的 extern xxx, 类型要一致
	var_t *cur;    
	var_t *same_scp_var = NULL;
	// 查询变量表
	hash_for_each_possible(sym_tab_g.var_tab, cur, hnode, key) {
		// 跳过错误的符号
   		if (!var->err_flag && 0 == strcmp(cur->name, var->name)) {  		
			if(in_same_scope(&cur->scope_path, &var->scope_path)) {
				same_scp_var = cur;
				break;
			}
        }
    }

	if(same_scp_var) {	
		if(!same_scp_var->is_ext) { // 遇到了变量定义
			// 重定义
			sem_err(VAR_REDEFINED, ERROR, var->name,  &same_scp_var->line_num);
			var_destroy(var);
			return;
		} else { // 遇到了声明
			if(IS_LOCAL(same_scp_var)) { // 局部的
				sem_err(EXTERN_DECLARATION_AND_NO_LINKAGE_DECLARATION_CONFLICTING, 
						ERROR, var->name,  &same_scp_var->line_num);
				var_destroy(var);
				return;
			} else { // 全局声明
				if(!var_type_exact_match(var, cur)) {
					sem_err(CONFLICTING_TYPES, ERROR, var->name, &cur->line_num);
					var_destroy(var);  
					return;
				} else {
					//删除全局声明
					hlist_del(&same_scp_var->hnode);
        			var_destroy(same_scp_var);  
					gp_list_del_node(same_scp_var, &sym_tab_g.var_tab_head);
				}
  				
			}
		}	
	}

	if(var->is_arr)
		gen_arr_init(var); // 会调用 add_var
	else 
		gen_var_init(var);

	hash_add(sym_tab_g.var_tab, &var->hnode, key);	
	gp_node_add_tail(var, &sym_tab_g.var_tab_head);
	sym_tab_g.var_num++;		
}

// 添加一个字符串常量到串表
void add_str(var_t *var)
{
	if(!var)
		return;
	sym_tab_g.str_num++;
	unsigned int key = my_hash(var->name); // name 不会重复
	hash_add(sym_tab_g.str_tab, &var->hnode, key);			
}



// 遵循就近原则
var_t *get_var(const char *name) 
{
	if(!name)
		return NULL;
	
	var_t *var_in_tab;
	var_t *find_var = NULL;
	scope_path_t tmp;

	unsigned int key = my_hash(name);
	get_cur_scope(&tmp, SYMBOL_TYPE_VAR);
	int tmp_len = tmp.path_len;
	int max_len = -1;

	hash_for_each_possible(sym_tab_g.var_tab, var_in_tab, hnode, key) {
    	if (!var_in_tab->err_flag && 0 == strcmp(var_in_tab->name, name)) {   
			int var_len = var_in_tab->scope_path.path_len;
			// 说明 var_in_tab 的作用域是 tmp 的前缀
			 if((tmp_len >= var_len) && 
			 		(var_in_tab->scope_path.path[var_len-1] == tmp.path[var_len-1])) {	
				if(var_len > max_len) {  // 寻找最长的前缀
					max_len = var_len;
					find_var = var_in_tab;
				}
			 }				
        }
    }

	free(tmp.path);
	return find_var;		
}


/*
	声明一个函数(不是定义)
	标识符相同，则应该参数列表、返回值一致；
	作用域相同的，只添加一个
*/
void decl_fun(fun_t *fun)
{
	if(!fun)
		return; 

	fun->is_ext = true; 
	var_t *var;
	unsigned int key = my_hash(fun->name);
	int conflict = 0;
	// 查询变量表
	hash_for_each_possible(sym_tab_g.var_tab, var, hnode, key) {
   		if (!var->err_flag && 0 == strcmp(var->name, fun->name)) {  
			if(in_same_scope(&var->scope_path, &fun->scope_path)) {
				conflict = 1;
				break;
			}
        }
    }

	if(conflict) {
		sem_err(REDECLARED_AS_DIFFERENT_KIND_SYMBOL, ERROR, 
				fun->name, &var->line_num);
		fun_destroy(fun);
		return;
	}
		
	int found = 0;
	fun_t *cur;
	fun_t  *declared_fun = NULL;
	int same_scope = 0;

	hash_for_each_possible(sym_tab_g.fun_tab, cur, hnode, key) {
        if (!cur->err_flag && 0 == strcmp(cur->name, fun->name)) {  
			found = 1;	
			declared_fun = cur;		    
			if(in_same_scope(&cur->scope_path, &fun->scope_path)) {
				same_scope = 1;	
				break;			
			}  						
        }
    }
// 即使不同作用域的函数声明，如果名字一样，那么类型要一致
// 定义了函数 xxx, 那么所有的 xxx 的函数声明，要和定义类型一致
	if(found){ 
		if(!fun_semantic_check_ok(declared_fun, fun)){
			// 因为表中的所有函数声明（包括定义）的参数列表和返回值是一致的，仅比较一个就可以        
			sem_err(CONFLICTING_TYPES, ERROR, fun->name, &declared_fun->line_num);		
			fun_destroy(fun); 
			return;
		}

		if(same_scope) { // 相同作用域的声明已经存在，不重复添加
			fun_destroy(fun); 
			return;
		}
	} 
	
	hash_add(sym_tab_g.fun_tab, &fun->hnode, key);
	sym_tab_g.fun_num++;
}
/*
	定义一个函数
*/
void def_fun(fun_t *fun)  // 末尾会设置 sym_tab.cur_fun 
{
	if(!fun)
		return; 
	var_t *var;
	int conflict = 0;
	// 查询变量表
	unsigned int key = my_hash(fun->name);
	hash_for_each_possible(sym_tab_g.var_tab, var, hnode, key) {
   		if (!var->err_flag && 0 == strcmp(var->name, fun->name)) {  
			if(in_same_scope(&var->scope_path, &fun->scope_path)) {
				conflict = 1;
				break;
			}
        }
    }
	if(conflict) {
		sem_err(REDECLARED_AS_DIFFERENT_KIND_SYMBOL, ERROR, fun->name, &var->line_num);
		fun->err_flag = 1;
	}

	fun_t *fun_in_tab;
	fun_t  *declared_fun = NULL;
	int same_scope = 0;
	hash_for_each_possible(sym_tab_g.fun_tab, fun_in_tab, hnode, key) {
        if (!fun_in_tab->err_flag && 0 == strcmp(fun_in_tab->name, fun->name)) { 
			declared_fun = fun_in_tab; 
			if(in_same_scope(&fun_in_tab->scope_path, &fun->scope_path)) {
				same_scope = 1;	
				break;			
			} 
        }
    }
	// 函数定义名字一样，类型不一样，gcc 报类型冲突；
	// 类型一样，gcc 报重复定义
	if(declared_fun) { 
		// 随便拿一个声明和定义都可以做类型检查，因为它们的类型是一致的
		if(!fun_semantic_check_ok(declared_fun, fun)) {        
			sem_err(CONFLICTING_TYPES, ERROR, fun->name,
					 &declared_fun->line_num);		
			fun->err_flag = 1;			
		} else {
			if(same_scope) {
				if(declared_fun->is_ext) { // 是声明，替换掉声明
					hlist_del(&declared_fun->hnode);
        			fun_destroy(declared_fun);
				} else { //  重复定义					
					sem_err(FUNCTION_REDEFINED, ERROR, 
						fun->name, &fun_in_tab->line_num);			
					fun->err_flag = 1;
				}
			}
		}
	}	
	// 添加函数到符号表
	hash_add(sym_tab_g.fun_tab, &fun->hnode, key);  
	sym_tab_g.fun_num++;
	sym_tab_g.cur_fun = fun;	// 当前分析的函数		
}



// 就近原则
fun_t *get_fun(const char *name) 
{
	if(!name)
		return NULL;
	scope_path_t tmp;
	get_cur_scope(&tmp, SYMBOL_TYPE_VAR);
	int tmp_len = tmp.path_len;
	int max_len = -1;
	fun_t *fun_in_tab;
	fun_t *find_fun = NULL;
	unsigned int key = my_hash(name);
	hash_for_each_possible(sym_tab_g.fun_tab, fun_in_tab, hnode, key) {
		if (!fun_in_tab->err_flag && 0 == strcmp(name, fun_in_tab->name)) {	
			int fun_len = fun_in_tab->scope_path.path_len;
			if((tmp_len >= fun_len)	&&
				(fun_in_tab->scope_path.path[fun_len-1] == tmp.path[fun_len-1])) {	
					if(fun_len > max_len) {  // 寻找最长的前缀
						max_len = fun_len;
						find_fun = fun_in_tab;
					}
			}	
		}
	}
	free(tmp.path);
	return find_fun;
}


// 遵循就近原则
sym_info_t get_var_or_fun(const char *name)  
{
	assert(name);
	sym_info_t sym_info = {NULL, 0};

	void *obj = NULL;
	var_t *var = get_var(name); 
	fun_t *fun = get_fun(name);
	if(!var && !fun) { // 没有找到
		return sym_info;
	}

	if(var && fun) { // 比较作用域
		if(var->scope_path.path_len > fun->scope_path.path_len) {
			obj = var;
			sym_info.sym_type = SYMBOL_TYPE_VAR;
		
		} else {
			obj = fun;
			sym_info.sym_type = SYMBOL_TYPE_FUN;
			
		}
	} else if(var) {
		obj = var;
		sym_info.sym_type = SYMBOL_TYPE_VAR;
	} else if(fun) {
		obj = fun;
		sym_info.sym_type = SYMBOL_TYPE_FUN;
	}
	sym_info.p_sym = obj;
	return sym_info;
}

// ------------ 工具函数 -----------

void show_var(var_t *var, int recursion)
{
	if(!var)
		return;
	if(var->err_flag) {
		printf(RED);
		printf("ERR ");
		printf(CLOSE);	
	}
    	
    printf("%d\t", var->index);

	if(var->is_ext)
		printf("extern\t");
    __print_type(var->type);      // 输出类型
    printf("\t");
	if(var->is_ptr) 
        printf("*"); // 输出指针
	printf("%s", var->name); //输出名字
	if(var->is_arr)
		printf("[%d]", var->ele_num); //输出数组

	printf("\t\t%d", var->size);

	if(var->is_literal) {
	 	printf("\t");
		print_literal(var);
		printf("\n");
		return;
	}
	printf("\t");
	print_scope_path(&var->scope_path);
	if(var->note && var->name[0] == '.')
		printf("\t\t%s ", var->note); // 临时变量输出 Note
	if(var->fun)
		printf("\t %s", var->fun->name); // 所属函数
	printf("\n");

	if(!recursion) 
		return;

	if(var->init_val && (!var->is_arr)) {		
		printf(HI_GRE);
		show_var(var->init_val, 0);	
		printf(CLOSE);
	} else if(var->is_arr && array_is_initialized(var)) {		
		print_array_init_val(var);
	}
}



void print_fun_para_list(fun_t *fun, int format)
{
    if(!fun)
        return;
	if(format != FUN_PARA_LIST_FORMAT_WITH_NAME)
		printf("(");
	gp_node_t *cur;
	var_t *var;
	int i = 0;
	
	if(fun->para_len){
	    list_for_each_entry(cur,  fun->para_list_head, entry) {
            var_t *var = cur->addr;
            if(var) {
				if(format == FUN_PARA_LIST_FORMAT_WITH_NAME) {
					printf("\t");			
					show_var(var, 1);
				} else {
            		__print_type(var->type);
            	
            		if(var->is_ptr || var->is_arr) {
            	    	printf("*"); // 输出指针
            		}   

            		if(++i < fun->para_len) {
            	    	printf(", ");
            		} 
				}
				 
            }
	    }
		

	} else {
		if(format == FUN_PARA_LIST_FORMAT_WITH_NAME)
			printf("\tvoid");
		else 
			printf("void");
	}
	if(format != FUN_PARA_LIST_FORMAT_WITH_NAME)
		printf(")");
	printf("\n");
  
}


// 打印函数表
void print_funs(void)
{
	printf("\n---------- 函数表 ---------\n");
    printf("sym_tab_g.fun_num = %d\n", sym_tab_g.fun_num);
  	fun_t *cur;
	unsigned bkt;
	hash_for_each(sym_tab_g.fun_tab, bkt, cur, hnode) {
		show_fun(cur);
		print_inter_code(&cur->inter_code);
	}
	printf("---------- End ----------\n");	
}

void show_fun(fun_t *fun)
{
	if(!fun)
        return;

	if(fun->err_flag) {
		printf(RED);
		printf("ERR ");
		printf(CLOSE);	
	}
    printf(HI_BLU);	
	// 输出返回值type
	__print_type(fun->type);
	if(fun->is_ptr)
		printf(" *");
	//输出名字
	printf(" %s", fun->name);

	if(fun->is_ext) {
		printf(";(声明)");
	}

	printf("\t");
	print_scope_path(&fun->scope_path);
	printf(CLOSE);	
	printf(HI_BLU);
	printf("\n参数:");
	//输出参数列表
	print_fun_para_list(fun, FUN_PARA_LIST_FORMAT_WITH_NAME);
	printf(CLOSE);
}



void print_literal(var_t *var)
{
	assert(var->is_literal);

	if(IS_BASE(var)) {
		if(var->type == CHAR)
        	printf("'%c'", var->char_val);
    	else if(var->type == INT)      
        	printf("%d", var->int_val);
	}
	else if(var->is_arr)
		printf("%s", var->string_val);
}



// 判断数组是否带初始化，检查 init_val 字段和  arr_init_val；
// init_val == NULL &&  arr_init_val 链表为空，说明没有初始化。
bool array_is_initialized(var_t *arr)
{
	if(!arr)
		return false;
	if(!arr->init_val && list_empty(&arr->arr_init_val))
		return false;
	else
		return true;
}

void print_array_init_val(var_t *arr) 
{
	if(arr->init_val) {
		//printf("\t初始化:");
		printf(HI_GRE);
		show_var(arr->init_val, 0);
		printf(CLOSE);
	} else {
		gp_node_t *node;
		list_for_each_entry(node, &arr->arr_init_val, entry) {
			var_t *var = node->addr;
			//printf("\t初始化:");
			printf(HI_GRE);
			show_var(var, 0);
			printf(CLOSE);
		}
	}
}


void print_vars_in_addition_order(void)
{
	printf("\n---------- 变量表 ---------\n");
    printf("sym_tab_g.var_num = %d\n", sym_tab_g.var_num);
	printf("sym_tab_g.literal_num = %d\n", sym_tab_g.literal_num);
		
    unsigned bkt;
	var_t *cur;
	gp_node_t *pos;
	printf("Index\tType\tName\t\tSize\tScp/Val\t\tNote\n");
	list_for_each_entry(pos, &sym_tab_g.var_tab_head, entry) {
		var_t *var = pos->addr;
		var_t *cur;
		unsigned int key = my_hash(var->name);
		hash_for_each_possible(sym_tab_g.var_tab, cur, hnode, key) {
			if(cur == var) {
				show_var(cur, 1); 
				break;
			}
		}
	}
	printf("---------- End ----------\n");
}




void print_vars_in_table(void)
{
	printf("\n---------- 变量表 ---------\n");
    unsigned bkt;
	var_t *cur;

	hash_for_each(sym_tab_g.var_tab, bkt, cur, hnode) {
		show_var(cur, 1); 
	}
	printf("---------- End ----------\n");
}

void print_strings(void)
{	
	printf("\n---------- 串表 ---------\n");
	printf("sym_tab_g.str_num = %d\n", sym_tab_g.str_num);
	var_t *cur;
	unsigned bkt;
	hash_for_each(sym_tab_g.str_tab, bkt, cur, hnode) {
		printf("%d\t%s\t", cur->index, cur->name);
		for(int i = 0; i < strlen(cur->string_val); ++i)
			show_ch_including_escape(cur->string_val[i]);

		printf("\n");
	}
	printf("---------- End ----------\n");
}


void __print_type(symbol_e type)
{
    if(type == CHAR)
        printf("char");
    else if(type == INT)    
        printf("int");
    else if(type == VOID)       
        printf("void");
}



void print_scope_path(scope_path_t *scope_path)
{
	assert(scope_path);

	if(scope_path->path){
		for(int i = 0; i < scope_path->path_len; ++i)
			printf("/%d",scope_path->path[i]);		
	} 
}


unsigned int my_hash(const char *name) 
{
    assert(name != NULL);
    unsigned int key = 0;

    while(*name) {
        key += *name;
        name++;
    }
    return key;
}